<?php

namespace app\common\service\lib;

use \Firebase\JWT\JWT as JwtVendor;
use Exception;

class Jwt
{
    /**
     * 生成jwt
     * @param int $uid
     * @return string
     */
    public static function signToken($data)
    {
        $key = config('setting.salt');   //加盐
        $token = array(
            "iss" => $key,        //签发者 可以为空
            "aud" => '',          //面向的用户，可以为空
            "iat" => time(),      //签发时间
            "nbf" => time() + 3,    //在什么时候jwt开始生效  （这里表示生成3秒后才生效）
            "exp" => time() + 7200, //token 过期时间
            "data" => $data,    //加密数据
        );

        $jwt['token'] = JwtVendor::encode($token, $key, "HS256");
        $jwt['expire'] = time() + 7000;
        return $jwt;
    }

    /**
     * 验证token
     * @param $token
     * @return array
     */
    public static function checkToken($token)
    {
        $key = config('setting.salt');
        $status = array("code" => 2);
        try {
            JwtVendor::$leeway = 60;//当前时间减去60，把时间留点余地
            //HS256方式，这里要和签发的时候对应
            $decoded = JwtVendor::decode($token, $key, array('HS256'));
            $arr = (array)$decoded;
            $res['code'] = 1;
            $res['data'] = $arr['data'];
            return $res;

        } catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
            $status['message'] = "签名不正确";
            return $status;
        } catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
            $status['message'] = "token失效";
            return $status;
        } catch (\Firebase\JWT\ExpiredException $e) { // token过期
            $status['message'] = "token失效";
            return $status;
        } catch (Exception $e) { //其他错误
            $status['message'] = "未知错误";
            return $status;
        }
    }

    /**
     * 刷新token
     * @param $token
     * @return array
     */
    public static function refreshToken($token)
    {
        $res = self::checkToken($token);

        if ($res['code'] == 2) {
            return ['code' => 400, 'data' => [], 'message' => $res['message']];
        }
        $token = self::signToken($res['data']);
        return ['code' => 200, 'data' => $token, 'message' => '刷新成功'];
    }
}